﻿//-----------------------------------------------------------------------------------
// Validation Rule Template version 1.0
//-----------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.WebTesting;
using System.Xml;
using System.Xml.XPath;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
namespace WebServicesTesting.Automation.WebTest.ValidationRules
{

    [System.ComponentModel.DisplayName("DataSetValidation")]
    [System.ComponentModel.Description("TODO: Add a more detailed description of 'DataSetValidation' validation rule.")]
    public class DataSetValidation : ValidationRule
    {

        #region Constructor
        /// <summary>
        /// standard constructor
        /// </summary>
        public DataSetValidation() { }
        #endregion

        #region Properties
        /*
         * Public properties on the class will be surfaced to the user in the VS UI.
         * Only string, int, and bool types are allowed.
         */

        /*
                /// <summary>
                /// Sample string property
                /// </summary>
                private string m_myStringProperty;
                [System.ComponentModel.DisplayName("My String Property")]
                [System.ComponentModel.Description("Enter a long description for this property.")]
                [System.ComponentModel.DefaultValue("MyString")]
                public string MyStringProperty
                {
                    get { return m_myStringProperty; }
                    set { m_myStringProperty = value; }
                }
        */

        /// <summary>
        /// Contains a message that is surfaced to the user
        /// </summary>
        private string xPathExpression;
        public string XPathExpression
        {
            get { return xPathExpression; }
            set { xPathExpression = value; }
        }

        private string connString;
        public string ConnString
        {
            get { return connString; }
            set { connString = value; }
        }

        private string query;
        public string Query
        {
            get { return query; }
            set { query = value; }
        }

        string contextParam;

        public string ContextParam
        {
            get { return contextParam; }
            set { contextParam = value; }
        }
        #endregion //Properties

        #region Validate Method

        /// <summary>
        /// A sample utility function that performs the actual work of validating values. 
        /// This demonstrates the best practice of moving most of the code out into 
        /// it's own function so you can test it from a unit test.
        /// </summary>
        /// <param name="sInputString">String to search</param>
        /// <param name="sReason">reason search failed</param>
        /// <returns>true - value found, false - value not found, reason contains more details</returns>
        private static bool Validate(string document)
        {
            Debug.Assert(document != null);

            // TODO:  Implement your Validation code here
            throw (new NotImplementedException("ValidationRule1:MyValidationFunction not implemented !"));

            // m_message = "Additional information regarding success/failure of function";
            // return true; // true if found, false if not found
        }

        /// <summary>
        /// The Validate method is called by the web test engine when the request is complete.
        /// e contains the request and response you need to validate.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// 
        public override void Validate(object sender, ValidationEventArgs e)
        {
           
            try
            {
                XmlDocument doc = e.Response.XmlDocument;

                XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
                nsMgr.AddNamespace("s", doc.DocumentElement.NamespaceURI);
                XPathNavigator nav = doc.CreateNavigator();
                XmlNode responseBody = doc.SelectSingleNode("//s:Body", nsMgr);
                string text = null;
                while (responseBody.HasChildNodes)
                {
                    text = responseBody.Name;
                    if (text == xPathExpression)
                    {
                        break;
                    }
                    else
                    {
                        responseBody = responseBody.LastChild;
                    }
                }

                XmlNodeList node = responseBody.ChildNodes;
                XmlNodeList k = null;
                XmlNode TableNode = null;
                string[,] strClient = null;
                int c = 0;
                string[] fname = null;
                int count = node.Count;
                

                for (int i = 0; i < count; i++)
                {
                    TableNode = node[i];
                    int j = 0;
                    if (TableNode.ChildNodes.Count > 0)
                    {
                        if (i == 0)
                        {
                            k = TableNode.ChildNodes;
                            c = k.Count;
                            fname = new string[c];
                            strClient = new string[count, c];

                        }
                        foreach (XmlNode p in TableNode)
                        {
                            strClient[i, j++] = p.InnerText;

                        }

                    }

                }

                string[,] table = new string[count, c];
                string connString = ConnString;
                string sql = Query;
                SqlConnection conn = new SqlConnection(connString);
                conn.Open();
                SqlDataAdapter da = new SqlDataAdapter(sql, conn);
                DataSet ds = new DataSet();
                da.Fill(ds);
                DataTable dt = ds.Tables[0];
                int row = 0, col = 0;
                foreach (DataRow rows in dt.Rows)
                {
                    foreach (DataColumn cols in dt.Columns)
                    {
                        table[row, col++] = rows[cols].ToString().Trim();
                    }
                    col = 0;
                    row++;
                }
                bool flag = true;
                for (int comp = 0; comp < count; comp++)
                {
                    for (int compn = 0; compn < c; compn++)
                    {
                        if (strClient[comp, compn].Trim() == table[comp, compn].Trim())
                        {
                            flag = true;
                        }
                        else
                        {
                            flag = false;
                        }
                    }
                }

                if (flag == true)
                {
                    e.WebTest.Context[ContextParam + "Validation"] = "True";
                    
                }
                else
                {
                    e.WebTest.Context[ContextParam + "Validation"] = "Fail";
              
                }


            }


            catch (Exception ex)
            {
                e.Message = String.Format(CultureInfo.CurrentCulture, "{ValidationRule1} Exception: {0}", ex.Message.ToString());
                e.IsValid = false;
            }
          
        }
        #endregion


        #region TestCode
        /*
        /// <summary>
        /// This section contains unit test that you can call to validate 
        /// that your function works correctly
        /// You should move this code to a test class.
        /// </summary>
        [TestMethod]
        public void Test_ValidationRule1_ValidationRule()
        {
            //
            //TODO:  Add valid test to confirm correct functionallity
            //
            // You should test for positive and non positive cases 
            
            // Positive test coniditions (value found)
            this.MyStringProperty = "test input";
            Assert.IsTrue(Validate("<html><body>sample html document</body></html>"));
            //
            // Non Positive Test conditions (value not found)
            this.MyStringProperty = "negative test input";
            Assert.IsFalse(Validate("<html><body>sample html document</body></html>"));
            Assert.IsTrue(Message.Compare("Expected message"), 0);
        }
        */
        #endregion
    }

}
